"""
Word文档解析器
处理 .docx 文件，支持文本、表格和图片提取
"""

import io
import logging
from typing import List
from .base_parser import BaseParser

# 导入Word处理库
try:
    import docx
    DOCX_AVAILABLE = True
except ImportError:
    DOCX_AVAILABLE = False

# 导入OCR库
try:
    from PIL import Image
    import pytesseract
    OCR_AVAILABLE = True
except ImportError:
    OCR_AVAILABLE = False

logger = logging.getLogger(__name__)


class DocxParser(BaseParser):
    """Word文档解析器"""
    
    def __init__(self):
        super().__init__()
        self.supported_extensions = ['.docx', '.doc']
    
    def parse_content(self, content: bytes) -> str:
        """解析Word文档内容"""
        if not DOCX_AVAILABLE:
            logger.error("python-docx库未安装，无法解析Word文档")
            return "Word文档解析失败：缺少依赖库"
        
        try:
            doc = docx.Document(io.BytesIO(content))
            text_content = []
            
            # 提取段落文本
            paragraph_texts = self._extract_paragraphs(doc)
            text_content.extend(paragraph_texts)
            
            # 提取表格内容
            table_texts = self._extract_tables(doc)
            if table_texts:
                text_content.append("\n[表格内容]:")
                text_content.extend(table_texts)
            
            # 提取图片中的文字（如果支持OCR）
            if OCR_AVAILABLE:
                try:
                    image_texts = self._extract_images_with_ocr(doc)
                    if image_texts:
                        text_content.append("\n[图片内容]:")
                        text_content.extend(image_texts)
                        logger.info(f"OCR识别到{len(image_texts)}个图片文本")
                except Exception as e:
                    logger.warning(f"Word图片OCR识别失败: {str(e)}")
            
            # 合并所有内容
            result = "\n".join(text_content)
            
            if not result.strip():
                return "Word文档解析完成，但未提取到内容"
            
            # 清理和提取有意义的内容
            cleaned_result = self.extract_meaningful_content(result)
            
            return cleaned_result if cleaned_result.strip() else "Word文档功能测试需求"
            
        except Exception as e:
            logger.error(f"解析Word文档失败: {str(e)}")
            return "Word文档解析失败"
    
    def _extract_paragraphs(self, doc) -> List[str]:
        """提取段落文本"""
        paragraphs = []
        
        for paragraph in doc.paragraphs:
            text = paragraph.text.strip()
            if text:
                paragraphs.append(text)
                logger.debug(f"提取段落文本，长度: {len(text)}")
        
        return paragraphs
    
    def _extract_tables(self, doc) -> List[str]:
        """提取表格内容"""
        table_texts = []
        
        for table_index, table in enumerate(doc.tables):
            table_content = []
            
            for row_index, row in enumerate(table.rows):
                row_text = []
                
                for cell in row.cells:
                    cell_text = cell.text.strip()
                    if cell_text:
                        row_text.append(cell_text)
                
                if row_text:
                    table_content.append(" | ".join(row_text))
                    logger.debug(f"提取表格{table_index+1}第{row_index+1}行，列数: {len(row_text)}")
            
            if table_content:
                table_texts.append(f"表格{table_index+1}:")
                table_texts.extend(table_content)
                table_texts.append("")  # 表格间空行
        
        return table_texts
    
    def _extract_images_with_ocr(self, doc) -> List[str]:
        """从Word文档中提取图片并进行OCR识别"""
        if not OCR_AVAILABLE:
            return []
        
        image_texts = []
        
        try:
            # 获取文档中的所有图片关系
            rels = doc.part.rels
            
            image_count = 0
            for rel in rels.values():
                if "image" in rel.target_ref:
                    try:
                        # 获取图片数据
                        image_data = rel.target_part.blob
                        
                        # 转换为PIL Image
                        pil_image = Image.open(io.BytesIO(image_data))
                        
                        # OCR识别
                        ocr_text = pytesseract.image_to_string(pil_image, lang='chi_sim+eng')
                        
                        if ocr_text.strip():
                            image_count += 1
                            image_texts.append(f"图片{image_count}: {ocr_text.strip()}")
                            logger.debug(f"OCR识别图片{image_count}，文本长度: {len(ocr_text)}")
                    
                    except Exception as e:
                        logger.debug(f"OCR识别图片失败: {str(e)}")
                        continue
        
        except Exception as e:
            logger.warning(f"Word图片提取失败: {str(e)}")
        
        return image_texts
    
    def get_document_info(self, content: bytes) -> dict:
        """获取Word文档信息"""
        info = {
            "paragraphs": 0,
            "tables": 0,
            "images": 0,
            "file_size": len(content)
        }
        
        if not DOCX_AVAILABLE:
            return info
        
        try:
            doc = docx.Document(io.BytesIO(content))
            
            # 统计段落数
            info["paragraphs"] = len([p for p in doc.paragraphs if p.text.strip()])
            
            # 统计表格数
            info["tables"] = len(doc.tables)
            
            # 统计图片数
            rels = doc.part.rels
            info["images"] = len([rel for rel in rels.values() if "image" in rel.target_ref])
            
        except Exception as e:
            logger.warning(f"获取Word文档信息失败: {str(e)}")
        
        return info
    
    def extract_styles_info(self, content: bytes) -> dict:
        """提取文档样式信息"""
        styles_info = {
            "headings": [],
            "lists": [],
            "emphasis": []
        }
        
        if not DOCX_AVAILABLE:
            return styles_info
        
        try:
            doc = docx.Document(io.BytesIO(content))
            
            for paragraph in doc.paragraphs:
                if not paragraph.text.strip():
                    continue
                
                # 检查标题样式
                if paragraph.style.name.startswith('Heading'):
                    level = paragraph.style.name.replace('Heading ', '')
                    styles_info["headings"].append({
                        "level": level,
                        "text": paragraph.text.strip()
                    })
                
                # 检查列表样式
                if paragraph.style.name.startswith('List'):
                    styles_info["lists"].append(paragraph.text.strip())
                
                # 检查强调文本
                for run in paragraph.runs:
                    if run.bold or run.italic:
                        styles_info["emphasis"].append(run.text.strip())
        
        except Exception as e:
            logger.warning(f"提取文档样式信息失败: {str(e)}")
        
        return styles_info
